<?php

namespace App\Listeners;

use Illuminate\Database\Events\QueryExecuted;

class DBQueryListener
{
    /**
     * @param QueryExecuted $event
     */
    public function handle(QueryExecuted $query)
    {
        if (strpos($query->sql, 'manager_logs') !== false) return;
        $request = request();
        if ($request->fullUrlIs('*/real-time-data/*')) return;
        // if ($query->time < 2) {
        //     return;
        // }

        $sqlWithPlaceholders = str_replace(['%', '?'], ['%%', '%s'], $query->sql);

        $bindings = $query->connection->prepareBindings($query->bindings);
        $pdo = $query->connection->getPdo();
        $realSql = $sqlWithPlaceholders;
        $duration = $this->formatDuration($query->time / 1000);

        if (count($bindings) > 0) {
            $realSql = vsprintf($sqlWithPlaceholders, array_map([$pdo, 'quote'], $bindings));
        }
        // 后台操作/控制台/API接口日志独立
        $requestUri = $request->getRequestUri();
        $logChannel = app()->runningInConsole() ? 'consoleSql' : (strpos($requestUri, '/admin/') !== false ? 'adminSql' : 'sql');

        \Log::channel($logChannel)->info(sprintf("[%s] [%s] %s | %s: %s", $query->connection->getDatabaseName(), $duration, $realSql,
            $request->method(), $requestUri));
    }


    /**
     * Format duration.
     *
     * @param  float  $seconds
     *
     * @return string
     */
    private function formatDuration($seconds)
    {
        if ($seconds < 0.001) {
            return round($seconds * 1000000).'μs';
        } elseif ($seconds < 1) {
            return round($seconds * 1000, 2).'ms';
        }

        return round($seconds, 2).'s';
    }
}
